﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Zzcore.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;

namespace Zzcore.Controllers
{
    public class RoleController : BaseController
    {
        private readonly ILogger<RoleController> _logger;
        public RoleController(ILogger<RoleController> logger, IFreeSql fsql) : base(fsql)
        {
            this._logger = logger;
        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> Index([FromForm] int doPage, [FromForm] int pageIndex = 1, [FromForm] int pageSize = 10)
        {
            List<Role> roles;
            long total = 0;
            if (doPage == 1)
            {
                roles = await _fsql.Select<Role>().Count(out total).Page(pageIndex, pageSize).ToListAsync();
            }
            else {
                roles = await _fsql.Select<Role>().ToListAsync();
            }

            JArray ja_role = new();
            if (roles != null && roles.Count > 0) {
                foreach (Role role in roles)
                {
                    List<long> uids = await _fsql.Select<RoleUser>().Where(ru => ru.Rid == role.Id).ToListAsync(ru => ru.Uid);
                    uids.Add(-1);
                    List<User> users = await _fsql.Select<User>().Where(u => uids.Contains(u.Id)).ToListAsync();
                    // 查询出来所有角色的用户
                    JObject jo_role = JObject.FromObject(role);
                    jo_role.Add("users", users == null ? null : JArray.FromObject(users));
                    ja_role.Add(jo_role);
                }
            }

            JObject data = new();
            data.Add("total", total);
            data.Add("list", ja_role);
            return RenderJson(data: data);
        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> Save([FromForm] Role role)
        {
            long id = await _fsql.Insert(role).ExecuteIdentityAsync();
            role.Id = id;

            return RenderJson(data: role);
        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> Delete([FromForm] long id) {
            // 删除该角色所有的用户
            await _fsql.Delete<RoleUser>().Where(ru => ru.Rid == id).ExecuteAffrowsAsync();
            // 删除该角色所有权限
            await _fsql.Delete<RolePermission>().Where(ru => ru.Rid == id).ExecuteAffrowsAsync();

            int affrows = await _fsql.Delete<Role>().Where(r => r.Id == id).ExecuteAffrowsAsync();
            return RenderJson(data: affrows);
        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> Update([FromForm] Role role) {
            int affrows = await _fsql.Update<Role>().SetSourceIgnore(role, colval => colval == null).ExecuteAffrowsAsync();
            return RenderJson(data: affrows);
        }

        [HttpPost]
        public async Task<IDictionary<string, Object>> Show([FromForm] long id) {
            Role role = await _fsql.Select<Role>().Where(d => d.Id == id).ToOneAsync();
            return RenderJson(data: role);
        }

        //[HttpPost]
        //public async Task<IActionResult> AddUser([FromForm] long rid, [FromForm] long[] uids)
        //{
        //    // 先清空该角色所有用户
        //    await _fsql.Delete<RoleUser>().Where(ru => ru.Rid == rid).ExecuteAffrowsAsync();

        //    List<RoleUser> roleusers = new();
        //    foreach (long uid in uids)
        //    {
        //        roleusers.Add(new RoleUser { Rid = rid, Uid = uid });
        //    }
        //    int affrows = await _fsql.Insert(roleusers).ExecuteAffrowsAsync();
        //    return new JsonResult(new { status = "success", message = "保存成功", code = 1, data = affrows });
        //}

        [HttpPost]
        public async Task<IActionResult> AddPermission([FromForm] long rid, [FromForm] long[] pmids)
        {
            // 先清空该角色所有权限
            await _fsql.Delete<RolePermission>().Where(rp => rp.Rid == rid).ExecuteAffrowsAsync();

            List<RolePermission> rolePermissions = new();
            foreach (long pmid in pmids)
            {
                rolePermissions.Add(new RolePermission { Rid = rid, Pmid = pmid });
            }
            int affrows = await _fsql.Insert(rolePermissions).ExecuteAffrowsAsync();
            return new JsonResult(new { status = "success", message = "保存成功", code = 1, data = affrows });
        }

        [HttpPost]
        public async Task<IActionResult> GetPermission([FromForm] long rid)
        {
            JArray data = new();
            if (rid == 1)
            {
                data = await GetAdminPermissionTreeData(0);
            }
            else {
                List<long> pmids = await _fsql.Select<RolePermission>().Where(rp => rp.Rid == rid).ToListAsync(rp => rp.Pmid);
                data = await GetRolePermissionTreeData(0, pmids);
            }
            return new JsonResult(new { status = "success", message = "获取成功", code = 1, data });
        }

        [NonAction]
        public async Task<JArray> GetRolePermissionTreeData(long pid, List<long> pmids)
        {
            JArray data = new();
            List<Permission> permissions = await _fsql.Select<Permission>().Where(p => p.Pid == pid).ToListAsync();
            if (permissions != null && permissions.Count > 0)
            {
                foreach (var permission in permissions)
                {
                    JObject jo_permission = JObject.FromObject(permission);
                    if (pmids.Contains(permission.Id))
                    {
                        jo_permission.Add("checked", true);
                    }
                    else {
                        jo_permission.Add("checked", false);
                    }
                    jo_permission.Add("children", GetRolePermissionTreeData(permission.Id, pmids).Result);
                    data.Add(jo_permission);
                }
            }

            return data;
        }

        [NonAction]
        public async Task<JArray> GetAdminPermissionTreeData(long pid)
        {
            JArray data = new();
            List<Permission> permissions = await _fsql.Select<Permission>().Where(p => p.Pid == pid).ToListAsync();
            if (permissions != null && permissions.Count > 0)
            {
                foreach (var permission in permissions)
                {
                    JObject jo_permission = JObject.FromObject(permission);
                    jo_permission.Add("checked", true);
                    jo_permission.Add("children", GetAdminPermissionTreeData(permission.Id).Result);
                    data.Add(jo_permission);
                }
            }

            return data;
        }

        [HttpPost]
        public async Task<IActionResult> AddUser([FromForm] long rid, [FromForm] long[] uids)
        {
            // 1.先清空当前角色所有用户
            await _fsql.Delete<RoleUser>().Where(ru => ru.Rid == rid).ExecuteAffrowsAsync();
            // 2.再从新增加所有用户
            long affrows = 0;
            if (uids?.Length > 0) {
                List<RoleUser> roleusers = new();
                foreach (var uid in uids)
                {
                    roleusers.Add(new RoleUser { Rid = rid, Uid = uid });
                }
                affrows = await _fsql.Insert<RoleUser>(roleusers).ExecuteAffrowsAsync();
            }
            return new JsonResult(new { status = "success", message = "获取成功", code = 1, data = affrows });
        }

        [HttpPost]
        public async Task<IActionResult> GetUser([FromForm] long rid, [FromForm] long did)
        {
            List<long> uids = await _fsql.Select<RoleUser>().Where(ru => ru.Rid == rid).ToListAsync(ru => ru.Uid);
            uids.Add(-1);
            List<User> znusers = await _fsql.Select<User>().Where(u => uids.Contains(u.Id)).ToListAsync();
            _logger.LogInformation("组内：" + _fsql.Select<User>().Where(u => uids.Contains(u.Id)).ToSql());
            List<User> zwusers = await _fsql.Select<User>().WhereIf(did != 0, u => u.Did == did).Where(u => !uids.Contains(u.Id)).ToListAsync();
            _logger.LogInformation("组外：" + _fsql.Select<User>().WhereIf(did != 0, u => u.Did == did).Where(u => !uids.Contains(u.Id)).ToSql());
            JObject data = new();
            data.Add("znusers", znusers == null ? null : JArray.FromObject(znusers));
            data.Add("zwusers", zwusers == null ? null : JArray.FromObject(zwusers));
            return new JsonResult(new { status = "success", message = "获取成功", code = 1, data });
        }
    }
}
